package demo.html2pdf;

import com.lowagie.text.Image;
import com.lowagie.text.pdf.BaseFont;
import org.apache.commons.io.IOUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.w3c.dom.Element;
import org.xhtmlrenderer.extend.FSImage;
import org.xhtmlrenderer.extend.ReplacedElement;
import org.xhtmlrenderer.extend.ReplacedElementFactory;
import org.xhtmlrenderer.extend.UserAgentCallback;
import org.xhtmlrenderer.layout.LayoutContext;
import org.xhtmlrenderer.layout.SharedContext;
import org.xhtmlrenderer.pdf.ITextFSImage;
import org.xhtmlrenderer.pdf.ITextImageElement;
import org.xhtmlrenderer.pdf.ITextRenderer;
import org.xhtmlrenderer.render.BlockBox;
import org.xhtmlrenderer.simple.extend.FormSubmissionListener;

import java.io.*;
import java.net.URL;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * html转PDF
 *
 * @author zhangxinbetter@qq.com
 * @since 2024/3/19 17:07
 */
public class Main {

    public static void main(String[] args) {
        useJsoupAndXhtmlrenderer();
    }

    private static void useJsoupAndXhtmlrenderer() {
        Document document = Jsoup.parse("<html>\n" +
                "    <head>\n" +
                "        <style>\n" +
                "            .body-style {\n" +
                "                border: 1px solid blue;\n" +
                "                margin-left: auto;\n" +
                "                margin-right: auto;\n" +
                "                width: 80%;\n" +
                "                background-color: #6AAB73;\n" +
                "                text-align: center;\n" +
                "            }\n" +
                "        </style>\n" +
                "        <link href=\"./style.css\" rel=\"stylesheet\">\n" +
                "    </head>\n" +
                "    <body>\n" +
                "        <div class=\"body-style\">\n" +
                "            <h1 class=\"h1-style\">Hello world!</h1>\n" +
                // "            <img src=\"https://avatars.githubusercontent.com/u/14057796?s=64&v=4\">\n" +
                "            <img src=\"test.png\">\n" +
                "        </div>\n" +
                "    </body>\n" +
                "</html>");

        document.outputSettings().syntax(Document.OutputSettings.Syntax.xml);

        // Files.newOutputStream(Paths.get("/Users/devin/Desktop/abc1.pdf"))
        try (OutputStream outputStream = new ByteArrayOutputStream()) {
            ITextRenderer renderer = new ITextRenderer();
            SharedContext sharedContext = renderer.getSharedContext();
            sharedContext.setPrint(true);
            sharedContext.setInteractive(false);

            // 如果有外链图片，可以使用 ReplacedElementFactory 处理
            sharedContext.setReplacedElementFactory(new LocalImageReplacedElementFactory());

            // 处理字体
            // 支持类路径
            renderer.getFontResolver().addFont("fonts/FangSong_GB2312.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);

            String baseUrl = null;
            // 如果有本地 css 样式文件，可以指定 baseUrl
            baseUrl = FileSystems.getDefault().getPath(".").toUri().toURL()
            + "/learn-java-lib/src/main/resources/html2pdf/";

            renderer.setDocumentFromString(document.html(), baseUrl);
            renderer.layout();
            renderer.createPDF(outputStream);
            System.out.println(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static class LocalImageReplacedElementFactory implements ReplacedElementFactory {
        @Override
        public ReplacedElement createReplacedElement(
                LayoutContext c, BlockBox box, UserAgentCallback uac, int cssWidth, int cssHeight) {
            Element e = box.getElement();
            String nodeName = e.getNodeName();
            if (nodeName.equals("img")) {
                String imagePath = e.getAttribute("src");
                try {
                    InputStream input;
                    if (imagePath.startsWith("http")) {
                        input = new URL(imagePath).openStream();
                    } else {
                        input = Files.newInputStream(Paths.get(FileSystems.getDefault().getPath(".").toAbsolutePath()
                                + "/learn-java-lib/src/main/resources/html2pdf/" + imagePath));
                    }
                    byte[] bytes = IOUtils.toByteArray(input);
                    Image image = Image.getInstance(bytes);
                    FSImage fsImage = new ITextFSImage(image);
                    if (cssWidth != -1 || cssHeight != -1) {
                        fsImage.scale(cssWidth, cssHeight);
                    } else {
                        fsImage.scale(2000, 1000);
                    }
                    return new ITextImageElement(fsImage);
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
            return null;
        }

        @Override
        public void reset() {
        }

        @Override
        public void remove(Element e) {
        }

        @Override
        public void setFormSubmissionListener(FormSubmissionListener listener) {
        }
    }

}